﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;

namespace ImpEx.Engine
{
    class WSSExportManifestFix
    {
        public static void Execute(SPSWebApplication app, string packDirectory)
        {
            XmlDocument doc = new XmlDocument();
            doc.Load(packDirectory + "\\manifest.xml");

            NonExportedItemsFix(doc, app);
            doc.Save(packDirectory + "\\manifest.xml");
        }

        public static void PageLayoutUrlFix(SPSWebApplication app, string packDirectory)
        {
            XmlDocument doc = new XmlDocument();
            doc.Load(packDirectory + "\\exportSettings.xml");
            string exportSiteUrl = doc.DocumentElement.Attributes["SiteUrl"].Value;
            string importSiteUrl = app.SPSSite.Url + 
                ((exportSiteUrl.EndsWith("/") && app.SPSSite.Url.EndsWith("/")) ? string.Empty : "/");

            doc.Load(packDirectory + "\\manifest.xml");

            XmlNamespaceManager mgr = new XmlNamespaceManager(doc.NameTable);
            mgr.AddNamespace("a", doc.DocumentElement.NamespaceURI);
            XmlNodeList publishLayoutNodes =
                doc.DocumentElement.SelectNodes("a:SPObject/a:File/a:Properties/a:Property[@Name=\"PublishingPageLayout\"]", mgr);

            foreach (XmlNode node in publishLayoutNodes)
                node.Attributes["Value"].Value = node.Attributes["Value"].Value.Replace(exportSiteUrl, importSiteUrl);

            doc.Save(packDirectory + "\\manifest.xml");
        }

        private static void DeleteExtraNode(XmlNode node, XmlDocument doc, XmlNamespaceManager mgr, List<XmlNode> markDeleted)
        {
            string url = (node.Attributes["Url"] != null) ? node.Attributes["Url"].Value : node.Attributes["Id"].Value;

            Logger.WriteLine("Fix manifest file: Exclude item: " + url);
            XmlNodeList childNodes =
                doc.DocumentElement.SelectNodes(
                    string.Format("a:SPObject[@ParentId=\"{0}\"]", node.Attributes["Id"].Value), mgr);

            if (childNodes != null)
            foreach (XmlNode childNode in childNodes)
                DeleteExtraNode(childNode, doc, mgr, markDeleted);

            markDeleted.Add(node);
        }

        private static void NonExportedItemsFix(XmlDocument doc, SPSWebApplication app)
        {
            XmlNamespaceManager mgr = new XmlNamespaceManager(doc.NameTable);
            mgr.AddNamespace("a", doc.DocumentElement.NamespaceURI);

            List<XmlNode> markDeleted = new List<XmlNode>();

            for (int i = 0; i < doc.DocumentElement.ChildNodes.Count; i++ )
            {
                XmlNode childNode = doc.DocumentElement.ChildNodes[i];
                string id = childNode.Attributes["Id"].Value;
                WSSObject obj = app.FindById(new Guid(id));

                if (obj != null && !obj.Exportable)
                {
                    DeleteExtraNode(childNode, doc, mgr, markDeleted);
                }
            }

            foreach (XmlNode node in markDeleted)
                if (node.ParentNode != null)
                    node.ParentNode.RemoveChild(node);
        }

    }
}
